/**
 * 因为本人编写这些数据结构的原因之一是为用于操作系统的实现，而在实现操作系统的过程中不能使用
 * libc，所以一些内存块的操作需要自己实现。
 * 
 * 目前只打算实现实现仓库内的数据结构所需要的函数。
 */

#ifndef _AHAMOLETT_DATA_STRUCT_STRING_H_
#define _AHAMOLETT_DATA_STRUCT_STRING_H_
#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>

/**
 * @brief 从 src 复制 n 个字符到 dest。
 * 
 * @param dest 储存被复制内容的内存地址。
 * @param src 被复制内容来源的内存地址。
 * @param n 复制的字节数。
 * 
 * @return void* 储存被复制内容的内存地址。
 */
static inline void *memcpy(void *dest, const void *src, size_t n)
{
    unsigned char *_dest = (unsigned char *)dest;
    unsigned char *_src = (unsigned char *)src;
    for (size_t cnt = 0; cnt < n; cnt++) {
        _dest[cnt] = _src[cnt];
    }
    return dest;
}

/**
 * @brief 用 c 填充首地址为 str ，长度为 n 的内存区域。
 * 
 * @param str 被填充的内存区域的首地址。
 * @param c 用于填充内存区域的字符，只有低八位有效。
 * @param n 填充的字节数。
 * 
 * @return void* 被填充的内存区域的首地址。
 */
static inline void *memset(void *str, int c, size_t n)
{
    unsigned char ch = (unsigned char)c;
    unsigned char *dest = (unsigned char *)str;
    for (size_t cnt = 0; cnt < n; cnt++) {
        dest[cnt] = ch;
    }
    return str;
}

/**
 * @brief 复制一个字符串。
 * 
 * 从头到位将 src 指向的字符串复制到 dest 中，复制的范围从最开始到第一个'\0'字符，包括'\0'
 * 字符。
 * 
 * @param dest 指向用于存储复制内容的目标数组。
 * @param src 要复制的字符串。
 * 
 * @return char* 指向最终的目标字符串 dest 的指针。
 */
static inline char *strcpy(char *dest, const char *src)
{
    int pos = 0;
    do {
        dest[pos] = src[pos];
        pos++;
    } while (src[pos] != '\0');
    return dest;
}

/**
 * @brief 获得一个字符串的长度。
 *
 * @param str 要求长度的字符串。
 *
 * @return size_t 字符串 str 的长度。
 */
static inline size_t strlen(const char* str)
{
    size_t count = 0;
    while (str[count] != '\0') {
        count += 1;
    }
    return count;
}

/**
 * @brief 有重叠情况的内存复制。
 *
 * @param str1 数据的目的地。
 * @param str2 数据来源。
 * @param n 要被复制的字节数。
 *
 * @return void* 该函数返回一个指向目标存储区 str1 的指针。
 */
static inline void *memmove(void *str1, const void *str2, size_t n)
{
    if (str2 > str1) {
        return memcpy(str1, str2, n);
    }
    unsigned char *_dest = (unsigned char *)str1;
    unsigned char *_src = (unsigned char *)str2;
    for (size_t cnt = 0; cnt < n; cnt++) {
        _dest[n - cnt] = _src[n - cnt];
    }
    return str1;
}

#ifdef __cplusplus
}
#endif
#endif
